/*
 * Yiven
 * 
 * jQuery ScrollPagination
 * 2020/02/17
 * last update 2021/2/2
 */

;(function($){
    // Check whether the object is a function
    let isFunction = function(obj){
        return Object.prototype.toString.call(obj) == '[object Function]';
    };
    // Element by element fade in code
    let fadeInWithDelay = function(loaded){
        let delay = 0;
        return $.each(loaded, function(){
            $(this).delay(delay).animate({opacity:1}, 200);
            delay += 100;
        });
    };

    let defaults = {
        url: null, // The url you are fetching the results.
        method: 'GET', // The method request.
        dataType: 'json', // Result data type.
        autoload: true, // Change this to false if you want to load manually, default true.
        data: {
            // These are the variables you can pass to the request, for example: which page you are
            page: 1, // Which page at the firsttime
            size: 10, // Number of pages
        }, 
        before: function(obj, opts){
            // Before load function, you can display a preloader div
            $(opts.loading).fadeIn();
        },
        render: null,// Render function.
        after: function(obj, opts){
            // After loading content, you can use this function to animate your new elements
            if(opts.autoload === true){
                $(opts.loading).fadeOut();
            }
            let objectsRendered = $(obj).children('[rel!=loaded]');
            fadeInWithDelay(objectsRendered);
        }, 
        scroller: $(window), // Who gonna scroll? default is the full window
        heightOffset: 20, // It gonna request when scroll is 10 pixels before the page ends
        loading: '#loading', // ID of loading prompt.
        loadingText: 'Wait a moment... it\'s loading!', // Text of loading prompt.
        loadingNomoreText: 'No more.', // No more of loading prompt.
        manuallyText: 'click to loading more.',
    };

    $.fn.scrollPagination = function(options) {
        let opts = $.extend(defaults, options);
        // let target = opts.scroller;
        return this.each(function() {
            init($(this), opts);
        });
    };

    let stopScrollPagination = function(obj=null, opts=null){
        if(obj == null){
            return $.each(obj, function() {
                $(this).attr('scrollPagination', 'disabled');
            });
        }else{
            $(opts.loading).text(opts.loadingNomoreText).fadeIn();
            $(obj).attr('scrollPagination', 'disabled');
        }
    };

    let loadContent = function(obj, opts){
        // Do before
        if (isFunction(opts.before)){
            opts.before(obj, opts);
        }
        $(obj).children().attr('rel', 'loaded');// Mark as loaded
        // Render the next page content
        $.ajax({
            type: opts.method,
            url: opts.url,
            data: opts.data,
            dataType: opts.dataType,
            success: function(data){
                if (isFunction(opts.render)){
                    opts.render(data, obj, opts);
                }else{
                    console.log(data);
                    var html = "";
                    if(data.content != null){
                        $(opts.loading).text(opts.loadingText);
                        dataCount = 0;
                        $.each(data.content,function(index, value){
                            html += "<li style='opacity:0;-moz-opacity: 0;filter: alpha(opacity=0);'><p>" + value + "</p></li>";
                            dataCount++;
                        });
                    }
                    
                    $(obj).append(html);// Appending
                    if(("pagesize" in data) && dataCount == data.pagesize){
                        opts.data.page++;
                    }else if(dataCount == opts.data.size){
                        opts.data.page++;
                    }else{
                        stopScrollPagination(obj, opts);//stop request
                    }
                }
                // Do after
                if (isFunction(opts.after)){
                    opts.after(obj, opts);
                }
            }
        });
    };

    let init = function(obj, opts){
        let target = opts.scroller;
        $(obj).attr('scrollPagination', 'enabled');//Pagination start
        if($(obj).children().length === 0){
            loadContent(obj, opts);//Request page 1
        }
    	currentPageNum = opts.data.page;
        if(opts.autoload === true){
            // A-mode;
            $(target).scroll(function(event){
                if($(obj).attr('scrollPagination') == 'enabled'){
                    let mayLoadContent = (Math.ceil($(target).scrollTop()) + opts.heightOffset) >= ($(document).height() - $(target).height());
                    if(mayLoadContent){
	                    currentPageNum++;//Avoid duplicate requests
                        if(currentPageNum<=opts.data.page){
                        	loadContent(obj, opts);
                    	}
                    }
                }else{
                    stopPropagation(obj, opts);
                }
            });
        }else{
            // M-mode';
            opts.loadingText = opts.manuallyText;
            $(opts.loading).text(opts.loadingText).fadeIn().on('click', function(event){
                if($(obj).attr('scrollPagination') == 'enabled'){
                    loadContent(obj, opts);
                }else{
                    stopPropagation(obj, opts);
                }
            });
        }
    };
})(jQuery);
